#include "csky_const_structs.h"
#include "csky_math.h"

int ls_fast_log(unsigned int x)
{
    static const int log_2[256] = {
        0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
        5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
        6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8};
    int l = -1;
    while (x >= 256) {
        l += 8;
        x >>= 8;
    }
    return l + log_2[x];
}

//fft 的取值为512，勿修改
/* ****this function would change the input***** */
void gen_power_spectrum(float *pcm_data_input, float *power_spectrum_output)
{
    // float *rfft_out = malloc(520 * sizeof(float));
    csky_rfft_fast_f32(&csky_rfft_sR_f32_len256, pcm_data_input, power_spectrum_output, 0);
    csky_cmplx_mag_f32(power_spectrum_output, power_spectrum_output, 129);
    // free(rfft_out);
    
    // memcpy(power_spectrum_output, rfft_out, 129 * sizeof(float));
    // for (int i = 0; i < 129; i++) {
    //     power_spectrum_output[i] = (float)ls_fast_log(power_spectrum_output[i]);
    // }
    // free(rfft_out);
}

//N=12的滑动平均算法
void gen_smooth_power_spectrum(float *pcm_data_input,float *power_spectrum_output)
{
    gen_power_spectrum(pcm_data_input,power_spectrum_output);

    // int  size = 129;
    // float Sum1 = 0, N = 12;
    // for (int j = 0; j < size; j++) {
    //     if (j < N / 2) {
    //         for (int k = 0; k < N; k++) {
    //             Sum1 += power_spectrum_output[j + k];
    //         }
    //         power_spectrum_output[j] = Sum1 / N;
    //     } else {
    //         if (j < size - N / 2) {
    //             for (int k = 0; k < N / 2; k++) {
    //                 Sum1 += (power_spectrum_output[j + k] + power_spectrum_output[j - k]);
    //             }
    //             power_spectrum_output[j] = Sum1 / N;
    //         } else {
    //             for (int k = 0; k < size - j; k++) {
    //                 Sum1 += power_spectrum_output[j + k];
    //             }
    //             for (int k = 0; k < (N - size + j); k++) {
    //                 Sum1 += power_spectrum_output[j - k];
    //             }
    //             power_spectrum_output[j] = Sum1 / N;
    //         }
    //     }

    //     Sum1 = 0;
    // }
}